use crate::unsafe_trait::Foo;

mod deref_raw_pointer;
mod extern_2_c;
mod unsafe_trait;

unsafe fn dangerous() {
    println!("dangerous");
}
extern "C"{ //"C" --> ABI --> Application Binary Interface.定义函数在汇编层的调用方式。 C - ABI遵从C语言的ABI。
    //extern "C" 是一个关键字组合，用来声明和定义外部函数接口（Foreign Function Interface, FFI）
    // 以便与使用C语言链接约定的代码（如C或C++代码）进行交互。这一机制允许Rust代码调用外部库中的函数或被其他语言（主要是C语言家族）调用。
    fn abs(input: i32) -> i32;
}
fn split_at_mut(values: &mut [i32], mid: usize) -> (&mut [i32], &mut [i32]) {
    let len = values.len();

    let ptr = values.as_mut_ptr();
    assert!(mid <= len);
    unsafe {
        (
            std::slice::from_raw_parts_mut(ptr, mid),
            std::slice::from_raw_parts_mut(ptr.add(mid), len - mid),
        )
    }
}
static HELLO_WORLD: &str = "Hello, world!"; //static variant.
static mut COUNTER:i32 = 0;
const THREE_HOURS_IN_SECONDS: i32 = 60 * 60 * 3;
fn add_to_count(v:i32){
    unsafe {
        COUNTER += v;
    }
}
fn main() {
    println!("Hello, world!");
    let address = 0x0123456usize;
    let r = address as *const i32;
    // unsafe {
    //     println!("{}", *r);
    // }
    // dangerous(); //call to unsafe function
    unsafe {
        dangerous();
    }
    let mut v = vec![1, 2, 3, 4, 5, 6];
    let (a, b) = split_at_mut(&mut v, 3);
    assert_eq!(a, &mut [1, 2, 3]);
    assert_eq!(b, &mut [4, 5, 6]);
    a.iter_mut().map(|x| *x *= 2);
    // println!("{:?}", &v);
    println!("{:?}", &a);
    a.iter_mut().for_each(|x| *x *= 2);
    println!("{:?}", &a);
    a.iter_mut().map(|x| *x *= 2); //.map没有改变原来的vec。
    println!("{:?}", &a);
    b.iter_mut().for_each(|x| *x *= 2);
    println!("{:?}", &b);

    unsafe {
        println!("abs(-3) = {}", abs(-3));
    }
    add_to_count(32);
    unsafe { println!("COUNTER: {}", COUNTER); } // sing static mutable is only allowed inside an `unsafe` block or function
    //可变静态变量，使用时必须使用unsafe块。
    let mut x = THREE_HOURS_IN_SECONDS; //常量可以被复制。
    println!("{}", x);
    unsafe {
        3.foo(); // 声明trait，并给已有类型实现trait。
        //类型和trait必须有一个是在当前crate。
    }
}
